using System.Collections.Generic;
using UnityEngine;

namespace Yoozoo.Gameplay.RTS
{
    /// <summary>
    /// 优化Animator Active造成的卡顿
    /// 
    /// </summary>
    public class EffectAnimatorData:MonoBehaviour
    {
        private List<GameObject> noAnimationGameObject = new List<GameObject>();
        private List<GameObject> fadeObjects = new List<GameObject>();
        private List<Animator> animators = new List<Animator>();
        private List<Material> materialList = new List<Material>();
        private List<float> materialInitColor = new List<float>();
        private float startFadeTime = 0;
        private float fadeTime;
        private bool hasInited = false;
        private static readonly int MMultiplier = Shader.PropertyToID("_MMultiplier");

        private void Awake()
        {
            Init();
        }

        private void CheckChild(Transform parent)
        {
            for (int i = 0; i < parent.childCount; i++)
            {
                var child = parent.GetChild(i);
                var animator = child.GetComponent<Animator>();
                if (animator != null)
                {
                    animators.Add(animator);
                    animator.enabled = false;
                }
                else
                {
                    var particle = child.GetComponent<ParticleSystem>();
                    if (particle != null)
                    {
                        noAnimationGameObject.Add(child.gameObject);
                    }
                    else
                    {
                        var mesh = child.GetComponent<MeshRenderer>();
                        if (mesh != null)
                        {
                            noAnimationGameObject.Add(child.gameObject);
                        }
                    }
                }
                CheckChild(child);
            }
        }

        private void InitFadeMaterial()
        {
            if (materialList.Count > 0)
            {
                for (int i = 0; i < materialList.Count; i++)
                {
                    materialList[i].SetFloat(MMultiplier,materialInitColor[i]);
                }
                return;
            }
            //for (int index = 0; index < fadeObjects.Count; index++)
            {
                var meshs = GetComponentsInChildren<MeshRenderer>();
                for (int i = 0; i < meshs.Length; i++)
                {
                    var mats = meshs[i].materials;
                    for (int j = 0; j < mats.Length; j++)
                    {
                        if (mats[j].shader.name == "Mobile/Effect/MixFx_OP")
                        {
                            materialList.Add(mats[j]);
                            materialInitColor.Add(mats[j].GetFloat(MMultiplier));
                        }
                    }
                }
                var particles = GetComponentsInChildren<ParticleSystem>();
                for (int i = 0; i < particles.Length; i++)
                {
                    var renderers = particles[i].GetComponentsInChildren<Renderer>();
                    for (int j = 0; j < renderers.Length; j++)
                    {
                        var mats = renderers[j].materials;
                        for (int k = 0; k < mats.Length; k++)
                        {
                            var mat = mats[k];
                            if (mat.shader.name == "Mobile/Effect/MixFx_OP")
                            {
                                materialList.Add(mat);
                                materialInitColor.Add(mat.GetFloat(MMultiplier));
                            }
                        }
                    }
                }
            }
        }

        private void Update()
        {
            if (startFadeTime > 0)
            {
                float currentTime = TimeUtils.GetClientTickTime() - startFadeTime;
                float percent = currentTime / fadeTime;
                if (percent > 1)
                {
                    SetMatColor(0);
                    startFadeTime = 0;
                }
                else
                {
                    SetMatColor(1 - percent);
                }
            }
        }

        private void SetMatColor(float percent)
        {
            for (int i = 0; i < materialList.Count; i++)
            {
                float color = materialInitColor[i] * percent;
                materialList[i].SetFloat(MMultiplier,color);
            }
        }

        public void StartFade(float time)
        {
            fadeTime = time;
            startFadeTime = TimeUtils.GetClientTickTime();
            InitFadeMaterial();
        }

        private void Init()
        {
            CheckChild(transform);
            hasInited = true;
        }
        
        public void SetActive(bool isActive)
        {
            if (!hasInited)
            {
                Init();
            }

            gameObject.transform.SetActive(isActive);
            return;

            for (int i = 0; i < noAnimationGameObject.Count; i++)
            {
                noAnimationGameObject[i].SetActive(isActive);
            }

            for (int i = 0; i < animators.Count; i++)
            {
                animators[i].enabled = isActive;
                if (isActive)
                {
                    var state = animators[i].GetCurrentAnimatorStateInfo(0);
                    animators[i].Play(state.fullPathHash,0,0);
                    animators[i].Update(0);
                }
            }

            if (isActive)
            {
                if (materialList.Count > 0)
                {
                    for (int i = 0; i < materialList.Count; i++)
                    {
                        materialList[i].SetFloat(MMultiplier,materialInitColor[i]);
                    }

                    startFadeTime = 0;
                }
            }

        }
    }
}
